package logic

import (
	"ahutoj/web/dao"
	"ahutoj/web/io/constanct"
	originJudged "ahutoj/web/service/originJudge/originjudged"
	"ahutoj/web/utils"
	"encoding/json"
	"errors"
	"fmt"
	"net/url"
	"regexp"
	"strings"
)

var problemURL = "https://www.luogu.com.cn/problem/"

type ProblemObj struct {
	Code            int    `json:"code"`
	CurrentTemplate string `json:"currentTemplate"`
	CurrentData     struct {
		Problem struct {
			Background   string     `json:"background"`
			Description  string     `json:"description"`
			InputFormat  string     `json:"inputFormat"`
			OutputFormat string     `json:"outputFormat"`
			Samples      [][]string `json:"samples"`
			Hint         string     `json:"hint"`
			Provider     struct {
				UID        int    `json:"uid"`
				Name       string `json:"name"`
				Slogan     string `json:"slogan"`
				Badge      string `json:"badge"`
				IsAdmin    bool   `json:"isAdmin"`
				IsBanned   bool   `json:"isBanned"`
				Color      string `json:"color"`
				CcfLevel   int    `json:"ccfLevel"`
				Background string `json:"background"`
			} `json:"provider"`
			Attachments []interface{} `json:"attachments"`
			CanEdit     bool          `json:"canEdit"`
			Limits      struct {
				Time   []int `json:"time"`
				Memory []int `json:"memory"`
			} `json:"limits"`
			StdCode string `json:"stdCode"`
			Vjudge  struct {
				Origin string `json:"origin"`
				Link   string `json:"link"`
				ID     string `json:"id"`
			} `json:"vjudge"`
			Translation      string `json:"translation"`
			Tags             []int  `json:"tags"`
			WantsTranslation bool   `json:"wantsTranslation"`
			TotalSubmit      int    `json:"totalSubmit"`
			TotalAccepted    int    `json:"totalAccepted"`
			Flag             int    `json:"flag"`
			Pid              string `json:"pid"`
			Title            string `json:"title"`
			Difficulty       int    `json:"difficulty"`
			FullScore        int    `json:"fullScore"`
			Type             string `json:"type"`
		} `json:"problem"`
		Contest     interface{} `json:"contest"`
		Discussions []struct {
			ID    int    `json:"id"`
			Title string `json:"title"`
			Forum struct {
				ID   int    `json:"id"`
				Name string `json:"name"`
				Slug string `json:"slug"`
			} `json:"forum"`
		} `json:"discussions"`
		Bookmarked      bool          `json:"bookmarked"`
		VjudgeUsername  interface{}   `json:"vjudgeUsername"`
		Recommendations []interface{} `json:"recommendations"`
		LastLanguage    int           `json:"lastLanguage"`
		LastCode        string        `json:"lastCode"`
		PrivilegedTeams []interface{} `json:"privilegedTeams"`
		UserTranslation interface{}   `json:"userTranslation"`
	} `json:"currentData"`
	CurrentTitle string      `json:"currentTitle"`
	CurrentTheme interface{} `json:"currentTheme"`
	CurrentTime  int         `json:"currentTime"`
}

func OrignProblemToMyProblem(Problem ProblemObj, origin originJudged.OJPlatform) dao.Problem {
	ret := dao.Problem{}
	ret.PID = OriginDefaultPID(Problem.CurrentData.Problem.Pid,origin)
	ret.PType = OriginDefaultPType(origin)
	ret.Title = OriginDefaultTitle(Problem.CurrentData.Problem.Title,origin)
	SamipleInPutAndOutPut := ""
	for idx := range Problem.CurrentData.Problem.Samples {
		SamipleInPutAndOutPut += fmt.Sprintf("### 样例输入 #%v\n\n```\n%v\n```\n\n### 样例输出 #%v\n\n```\n%v\n```\n\n",
			idx,
			Problem.CurrentData.Problem.Samples[idx][0],
			idx,
			Problem.CurrentData.Problem.Samples[idx][1],
		)
	}
	description := fmt.Sprintf("## 题目描述\n\n%v\n\n## 输入格式\n\n%v\n\n## 输出格式\n\n%v\n\n题目样例\n\n%v\n\n## 提示\n\n%v",
		Problem.CurrentData.Problem.Description,
		Problem.CurrentData.Problem.InputFormat,
		Problem.CurrentData.Problem.OutputFormat,
		SamipleInPutAndOutPut,
		Problem.CurrentData.Problem.Hint,
	)
	ret.LimitTime = int64(Problem.CurrentData.Problem.Limits.Time[0])
	ret.LimitMemory = int64(Problem.CurrentData.Problem.Limits.Memory[0] / 1024)
	ret.ContentType = 1
	ret.Origin = int64(origin)
	ret.OriginPID = OriginDefaultOriginPID(Problem.CurrentData.Problem.Pid,origin)
	ret.Visible = 1
	// ret.OriginPID = 
	// CFCID, CFCIDX, _ := parsePID(ret.OriginPID)
	ret.Description = description
	//+ "\n" + fmt.Sprintf(`<a href="https://codeforces.com/contest/%v/problem/%v" target="_blank">点击查看原题</a>`,
	// 	CFCID,
	// 	CFCIDX,
	// )
	return ret
}

func pURL(originPID string,origin int64)string{
	url := ""
	switch origin {
	case 1:
		url=fmt.Sprintf("CF%v", originPID)
	case 2:
		url=fmt.Sprintf("AT_%v", originPID)
	}
	return problemURL+url
}//通过originPID 构造洛谷题目链接格式

func OriginDefaultPType(origin originJudged.OJPlatform)constanct.ProblemType{
	switch origin {
	case 1:
		return constanct.CODEFORCESTYPE
	case 2:
		return constanct.ATCODERTYPE
	default:
		return constanct.LOCALTYPE
	}
}//默认的PType类型

func OriginDefaultPID(PID string,origin originJudged.OJPlatform)string{
	switch origin {
	case 1:
		return "CF"+PID
	case 2://atcoder
		re := regexp.MustCompile(`^AT_(.*)$`)
		extracted := re.ReplaceAllString(PID, "$1")
		result := strings.ToUpper(strings.ReplaceAll(extracted, "_", ""))
		return result
	default:
		return PID
	}
}//默认的PID

func OriginDefaultOriginPID(PID string,origin originJudged.OJPlatform)string{
	switch origin {
	case 1:
		return PID[2:]
	case 2://atcoder
		return PID[3:]
	default:
		return PID
	}
}

func OriginDefaultTitle(PID string,origin originJudged.OJPlatform)string{
	switch origin {
	case 2://atcoder
		re := regexp.MustCompile(`\[.*?\]`)
		result := re.ReplaceAllString(PID, "")
		return result
	default:
		return PID
	}
}

func ParseProblemURL(originPID string,origin int64) (dao.Problem, error) {
	Purl := pURL(originPID,origin)
	resp, err := utils.DoRequest(utils.GET, Purl, nil, nil, nil,utils.WithoutRedirect)
	if err != nil {
		return dao.Problem{}, fmt.Errorf("call Dorequest Failed,err:%v", err.Error())
	}
	body, err := utils.ParseRespToByte(resp)
	if err != nil {
		return dao.Problem{}, err
	}
	// re := regexp.MustCompile(`<article>(?s:(.*?))</article>`)
	re := regexp.MustCompile(`JSON.parse\(decodeURIComponent\("(?s:(.*?))"\)`)
	jsonCode := re.FindSubmatch(body)
	if jsonCode == nil {
		return dao.Problem{}, fmt.Errorf("parse html failed")
	}
	// 使用正则表达式进行替换
	Pjson, _ := url.QueryUnescape(string(jsonCode[1]))

	re2 := regexp.MustCompile(`\$(.*?)\$`)
	formattedText := re2.ReplaceAllStringFunc(Pjson, func(s string) string {
		// 去除内容两侧的空格
		r := regexp.MustCompile(`^\s*|\s*$`)
		return "$" + r.ReplaceAllString(re2.FindStringSubmatch(s)[1], "") + "$"
	})
	// fmt.Println(formattedText)//$ n $ -> $n$

	problem := ProblemObj{}
	json.Unmarshal([]byte(formattedText), &problem)
	if len(problem.CurrentData.Problem.Pid) < 3 {
		return dao.Problem{}, errors.New("parse pid failed")
	}
	myproblem := OrignProblemToMyProblem(problem,originJudged.OJPlatform(origin))
	return myproblem, nil
}
